package ddz.core.dealer;

import ddz.core.Cards;
import ddz.core.SuitType;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 发牌器
 *
 * @author zkpursuit
 */
public class Dealer {
    /**
     * 54张牌的集合
     */
    protected final List<Integer> cards;
    protected final int several; //1副牌
    protected transient final Random random = new Random();

    public Dealer() {
        this(1);
    }

    /**
     * 构造方法
     */
    public Dealer(int several) {
        this.several = several;
        this.cards = new ArrayList<>(54 * several);
    }

    /**
     * 初始化
     */
    protected void init() {
        SuitType[] types = SuitType.values();
        for (int n = 0; n < several; n++) {
            for (SuitType type : types) {
                int baseValue = type.getId() * 100;
                if (type == SuitType.dawang || type == SuitType.xiaowang) {
                    cards.add(baseValue);
                } else {
                    for (int j = 2; j <= 14; j++) {
                        cards.add(baseValue + j);
                    }
                }
            }
        }
    }

    /**
     * 每次有序牌，模拟现实每次都是洗的一副新牌 交换法洗牌，扑克牌洗牌通用
     */
    protected void shuffle() {
        cards.clear();
        init();
        int n = cards.size();
        int i = n - 1;
        do {
            int rn = random.nextInt(i + 1);
            if (rn == i) {
                continue;
            }
            int temp = cards.get(rn);
            cards.set(rn, cards.get(i));
            cards.set(i, temp);
            --i;
        } while (i > 0);
    }

    /**
     * 发牌，分配牌数据
     *
     * @param array         玩家手牌数组
     * @param excludeAmount 排除的数量，一般作为底牌
     * @param oneAmount     每次分配的数量
     */
    protected void distribute(Cards[] array, int excludeAmount, int oneAmount) {
        int num = cards.size() - excludeAmount;
        int startNum = num; //初始分配量，即需要分多少次把这些数量的牌分配到三个玩家手牌中
        int endNum = 0; //剩余分配量，除去初始分配后将此数量的牌平均分配到玩家手牌中
        int average = array.length * oneAmount; //每个玩家最初平均分配的牌数量
        //计算初始分配量和剩余分配量
        for (int i = 1; i <= 10; i++) {
            endNum = array.length * i;
            int remaing = num - endNum;
            if (remaing % average == 0) {
                startNum = remaing;
                break;
            }
        }
        int count = startNum / (array.length * oneAmount); //
        for (int i = 0; i < count; i++) {
            for (Cards handCards : array) {
                for (int j = 0; j < oneAmount; j++) {
                    int card = cards.remove(0);
                    handCards.addCard(card);
                }
            }
        }
        int step = endNum / array.length; //剩余的牌每个玩家可以分配的平均数量
        for (Cards handCards : array) {
            for (int j = 0; j < step; j++) {
                int card = cards.remove(0);
                handCards.addCard(card);
            }
        }
    }

    /**
     * 发牌分配（模拟真实发牌机制）
     *
     * @param array   各玩家手牌
     * @param remaing 需要剩余的数量
     */
    public void distribute(Cards[] array, int remaing) {
        shuffle();
        distribute(array, remaing, 5);
    }

//    public int[] remainingCards() {
//        int[] _cards = new int[cards.size()];
//        for (int i = 0; i < _cards.length; i++) {
//            _cards[i] = cards.get(i);
//        }
//        return _cards;
//    }

    public int[] diPai() {
        if (cards.isEmpty()) return null;
        int last = cards.size() - 1;
        int[] _cards = new int[3];
        for (int i = 0; i < _cards.length; i++) {
            _cards[i] = cards.get(last);
            last--;
        }
        return _cards;
    }

}
